#include "Md5Util.h"
#include <QCryptographicHash>
#include <QFile>

QString hmacSha1(QByteArray key, QByteArray baseString){
    int blockSize = 64; // HMAC-SHA-1 block size, defined in SHA-1 standard
    if (key.length() > blockSize) { // if key is longer than block size (64), reduce key length with SHA-1 compression
        key = QCryptographicHash::hash(key, QCryptographicHash::Sha1);
    }

    QByteArray innerPadding(blockSize, char(0x36)); // initialize inner padding with char "6"
    QByteArray outerPadding(blockSize, char(0x5c)); // initialize outer padding with char "quot;

    for (int i = 0; i < key.length(); i++) {
        innerPadding[i] = innerPadding[i] ^ key.at(i); // XOR operation between every byte in key and innerpadding, of key length
        outerPadding[i] = outerPadding[i] ^ key.at(i); // XOR operation between every byte in key and outerpadding, of key length
    }
    QByteArray total = outerPadding;
    QByteArray part = innerPadding;
    part.append(baseString);
    total.append(QCryptographicHash::hash(part, QCryptographicHash::Sha1));
    QByteArray hashed = QCryptographicHash::hash(total, QCryptographicHash::Sha1);
    return hashed.toBase64();
}

QString getHashMd5(const QByteArray &data)
{
    QString md5;
    QByteArray array = QCryptographicHash::hash(data,QCryptographicHash::Md5);
    md5 = QString(array.toHex());
    return md5;
}

QString getHashMd5(const QString &filePath){
    QString md5;
    QFile file(filePath);
    if(file.open(QIODevice::ReadOnly)){
        return getHashMd5(file.readAll());//file为栈变量，函数结束自动关闭
    }
    file.close();
    return md5;
}

std::string GetFileMD5A(const QString& strFilePath)
{
    const int  nBuffSize = 1024 * 64;
    char *buff = NULL;
    int64_t dwLength = 0;

    QCryptographicHash ch(QCryptographicHash::Md5);

    QFile hFile(strFilePath);
    if (!hFile.open(QIODevice::ReadOnly)) {
        return ("");
    }

    buff = (char *)malloc(nBuffSize);
    memset(buff, 0, nBuffSize);
    while ((dwLength = hFile.read(buff, nBuffSize)) && (dwLength > 0))
    {
        ch.addData(buff,dwLength);
        memset(buff, 0, nBuffSize);
    }
    hFile.close();
    delete buff;
    std::string sResult = QString(ch.result().toHex()).toStdString();
    return sResult;
}
